/*******************************************************************
 *   > File Name: key.c
 *   > Author: fly
 *   > Mail: XXXXXXXX@icode.com
 *   > Create Time: 2020年12月07日 星期一 19时52分42秒
 ******************************************************************/
#include "key.h"
#include "uart.h"
#include "int.h"
#include "printf.h"

// -------------------中断方式处理按键-------------------------------
// 以中断方式来处理按键的初始化
void key_init_interrupt(void)
{
	// 1.外部中断对应的GPIO模式设置
	rGPH0CON |= 0xFF << 8;		// GPH0_2/GPH0_3设置为外部中断模式
	rGPH2CON |= 0xFFFF << 0;	// GPH2_0/1/2/3共4个引脚设置为外部中断模式

	// 2.中断触发模式设置
	rEXT_INT_0_CON &= ~(0xFF<<8);			// bit8~15全部清零
	rEXT_INT_0_CON |= ((2<<8) | (2<<12));	// EXT_INT2和EXT_INT3设置为下降沿触发
	rEXT_INT_2_CON &= ~(0xFFFF<<0);
	rEXT_INT_2_CON |= ((2<<0) | (2<<4) | (2<<8) | (2<<12));

	// 3.中断允许
	rEXT_INT_0_MASK &= ~(0x03<<2);
	rEXT_INT_2_MASK &= ~(0x0F<<0);

	// 4.清挂起，清除是写1,
	rEXT_INT_0_PEND |= (0x03<<2);
	rEXT_INT_2_PEND |= (0x0F<<0);
}

// EINT2通道对应的按键，就是GPH0_2引脚对应的按键，
// 就是开发板上标了LEFT的那个按键
void isr_eint2(void)
{
	// 真正的isr应该做2件事情。
	// 第一，中断处理代码，就是真正干活的代码
	printf("isr_eint2_LEFT.\n\r");
	uart2_printf("isr_eint2_LEFT.\n\r");
	// 第二，清除中断挂起
	rEXT_INT_0_PEND |= (1<<2);
	intc_clearvectaddr();
}

void isr_eint3(void)
{
	// 真正的isr应该做2件事情。
	// 第一，中断处理代码，就是真正干活的代码
	printf("isr_eint3_DOWN.\n\r");
	uart2_printf("isr_eint3_DOWN.\n\r");
	// 第二，清除中断挂起
	rEXT_INT_0_PEND |= (1<<3);
	intc_clearvectaddr();
}

void isr_eint16171819(void)
{
	// 第一，中断处理代码；
	// 因为EINT16~31是共享中断，所以
	// 要在这里再次去区分具体是哪个子中断
	if(rEXT_INT_2_PEND & (1 << 0))
	{
		printf("eint16_UP.\n\r");
		uart2_printf("eint16_UP.\n\r");
	}
	if(rEXT_INT_2_PEND & (1 << 1))
	{
		printf("eint17_RIGHT.\n\r");
		uart2_printf("eint17_RIGHT.\n\r");
	}
	if(rEXT_INT_2_PEND & (1 << 2))
	{
		printf("eint18_BACK.\n\r");
		uart2_printf("eint18_BACK.\n\r");
	}
	if(rEXT_INT_2_PEND & (1 << 3))
	{
		printf("eint19_MENU.\n\r");
		uart2_printf("eint19_MENU.\n\r");
	}

	// 第二，清除中断挂起
	rEXT_INT_2_PEND |= (0x0F << 0);
	intc_clearvectaddr();
}

void tester_key_int(void)
{
	key_init_interrupt();
	// 如果程序要使用中断，就要调用中断初始化来
	// 初步初始化中断控制器
	system_init_exception();

	// 绑定isr到中断控制器
	intc_setvectaddr(KEY_EINT2, isr_eint2);
	intc_setvectaddr(KEY_EINT3, isr_eint3);
	intc_setvectaddr(KEY_EINT16_19, isr_eint16171819);

	// 使能中断
	intc_enable(KEY_EINT2);
	intc_enable(KEY_EINT3);
	intc_enable(KEY_EINT16_19);
}
